package edu.bbu.cshu.wmpc.checking.similarity.dice;

import java.util.ArrayList;

import edu.bbu.cshu.wmpc.checking.similarity.Similarity;
/**
 * <ul>
 * <li><b><i>DiceCoefficient</i></b></li>
 * <li style="list-style: none;"></li>
 * <li style="list-style: none;">
 * Class that extends {@link Similarity} and implements the {@code dice coefficient} similarity test.
 * 
 * @author WMPC team
 * </li>
 * </ul>
 */ 
public class DiceCoefficient extends Similarity {
	/**
	 * <ul>
	 * <li><b><i>line1</i></b></li>
	 * <li style="list-style: none;"></li>
	 * <li style="list-style: none;">
	 * {@link ArrayList}<{@link String}> that contains the first {@code String}. The {@code String} has be processed into characters and character pairs.
	 * 
	 * </li>
	 * </ul>
	 */
	private ArrayList<String> line1;
	/**
	 * <ul>
	 * <li><b><i>line1</i></b></li>
	 * <li style="list-style: none;"></li>
	 * <li style="list-style: none;">
	 * {@link ArrayList}<{@link String}> that contains the second {@code String}. The {@code String} has be processed into characters and character pairs.
	 * 
	 * </li>
	 * </ul>
	 */
	private ArrayList<String> line2;
	/**
	 * <ul style="margin-top: 24px;">
	 * <li><b><i>DiceCoefficient</i></b></li>
	 * <li style="list-style: none;"></li>
	 * <li style="list-style: none;">
	 * <p style="margin-left: 7px;">{@code public DiceCoefficient(double limit)}</p>
	 * <br>	
	 * Constructor that sets the value of {@code limit}.
	 * 
	 * @param limit - the limit at which two lines are considered similar
	 * </li>
	 * </ul>
	 */
	public DiceCoefficient(double limit) {
		this.limit = limit;
	}

	protected void setString(int index, String str) {
		switch (index) {
			case 1: line1 = new ArrayList<String>(); break;
			case 2: line2 = new ArrayList<String>(); break;
		}

		char tmp1;
		char tmp2;
		int length = str.length()-1;
		char[] ch = str.toCharArray();

		for (int i = 0; i < length; i++) {
			tmp1 = ch[i];
			
			if (specia.indexOf(tmp1) != -1) {
				tmp2 = ch[i+1];
				
				if (specia.indexOf(tmp2) != -1) {
					addToLine(index, tmp1, tmp2);
					i++;
				} else {
					addToLine(index, tmp1);
				}
			} else {
				if (!Character.isWhitespace(tmp1) && Character.isLetterOrDigit(tmp1)) {
					tmp2 = ch[i+1];
	
					if (!Character.isWhitespace(tmp2) && Character.isLetterOrDigit(tmp2)) { 					
						addToLine(index, tmp1, tmp2);			
					}
				}
			}
		}
	}
	/**
	 * <ul style="margin-top: 24px;">
	 * <li><b><i>addToLine</i></b></li>
	 * <li style="list-style: none;"></li>
	 * <li style="list-style: none;">
	 * <p style="margin-left: 7px;">{@code private void addToLine(int index, char tmp1)}</p>
	 * <br>	
	 * Adds {@code tmp1} to {@code line1} or {@code line2} depending on the {@code index}.
	 * 
	 * @param index - specifies to which {@code String} the {@code char} is to be added
	 * @param tmp1	- the character to be added
	 * </li>
	 * </ul>
	 */
	private void addToLine(int index, char tmp1){
		switch (index) {
			case 1: line1.add("" + Character.toLowerCase(tmp1)); break;
			case 2: line2.add("" + Character.toLowerCase(tmp1)); break;
		}
	}
	/**
	 * <ul style="margin-top: 24px;">
	 * <li><b><i>addToLine</i></b></li>
	 * <li style="list-style: none;"></li>
	 * <li style="list-style: none;">
	 * <p style="margin-left: 7px;">{@code private void addToLine(int index, char tmp1, char tmp2)}</p>
	 * <br>	
	 * Adds {@code tmp1tmp2 char} pair to {@code line1} or {@code line2} depending on the {@code index}.
	 * 
	 * @param index - specifies to which {@code String} the {@code char} pair is to be added
	 * @param tmp1	- the first character of the pair to be added
	 * @param tmp2	- the second character of the pair to be added
	 * </li>
	 * </ul>
	 */
	private void addToLine(int index, char tmp1, char tmp2){
		switch (index) {
			case 1: line1.add("" + Character.toLowerCase(tmp1) + Character.toLowerCase(tmp2)); break;
			case 2: line2.add("" + Character.toLowerCase(tmp1) + Character.toLowerCase(tmp2)); break;
		}
	}

	protected double executeStringTest() {
		ArrayList<String> engraving = new ArrayList<String>(line1);
		engraving.retainAll(line2);
		return (double)(2*engraving.size()) / (line1.size() + line2.size());
	}

}
